"""
@Author :江上挽风&sty
@Blog(个人博客地址):https://blog.csdn.net/weixin_56097064
@File :B站视频爬取
@Time :2024/12/11 9:28
@Motto:一直努力，一直奋进，保持平常心
"""
import os
import pprint
import re

# 1、爬取视频页的网页源代码
import requests
import json
from lxml import etree

header = {
    "referer": "https://www.bilibili.com",
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0"
}


# 2、提取视频和音频的播放地址
def get_play_url(url):
    r = requests.get(url, headers=header)
    # print(r.text)
    info = re.findall('window.__playinfo__=(.*?)</script>', r.text)[0]
    video_url = json.loads(info)["data"]["dash"]["video"][0]["baseUrl"]
    audio_url = json.loads(info)["data"]["dash"]["audio"][0]["baseUrl"]
    # print(video_url)
    # print(audio_url)
    html = etree.HTML(r.text)
    filename = html.xpath('//h1/text()')[0]
    # print(filename)
    return video_url, audio_url, filename


# 3、下载并保存视频和音频
def download_files(video_url, audio_url, filename, video_path, audio_path):
    print("开始下载视频和音频")
    video_content = requests.get(video_url, headers=header).content
    audio_content = requests.get(audio_url, headers=header).content

    with open(f'{video_path}/{filename}.mp4', 'wb') as f:
        f.write(video_content)
        print("视频部分下载完毕")
    with open(f'{audio_path}/{filename}.mp3', 'wb') as f:
        f.write(audio_content)
        print("音频部分下载完毕")


# 4、合并视频和音频,使用ffmpeg模块
def combin_video_audio(filename, video_path, audio_path):
    # cmd = fr"ffmpeg -i {video_path}{filename}.mp4 -i {audio_path}{filename}.mp3 -c:v copy -c:a aac -strict experimental -map 0:v -map 1:a {video_path}\output-{filename}.mp4 -loglevel quiet"  # -loglevel quiet 表示隐藏日志，不加问题不大
    cmd = fr"ffmpeg -i {video_path}/{filename}.mp4 -i {audio_path}/{filename}.mp3 -c:v copy -c:a aac -strict experimental -map 0:v -map 1:a videos/{filename}.mp4 -loglevel quiet"  # -loglevel quiet 表示隐藏日志，不加问题不大
    os.system(cmd)
    print("音频视频合并完毕")
    print("--" * 10)
    os.remove(f'{video_path}/{filename}.mp4')
    os.remove(f'{audio_path}/{filename}.mp3')
    print('已删除多余的文件')


if __name__ == '__main__':
    with open("link.txt", "r", encoding="utf-8") as f:
        texts = f.readlines()
        f.close()
    for link in texts:
        link = link.strip()
        video_url, audio_url, filename = get_play_url(link)
        pattern = re.compile(r'[^\u4e00-\u9fa5a-zA-Z0-9]')
        # 替换非目标字符为空
        filename  = re.sub(pattern, '_', filename)
        if os.path.exists(f"videos/{filename}.mp4"):
            continue
        try:
            download_files(video_url, audio_url, filename, "vid", "aid")
            combin_video_audio(filename,"vid", "aid")
        except:
            pass